package asteroids.entity;

import org.apache.log4j.Logger;

import asteroids.engine.GameState;
import asteroids.engine.Utils;
import asteroids.engine.ai.Pilot;
import asteroids.engine.ai.StreakyPilot;
import asteroids.entity.weapon.Bullet;
import asteroids.factory.ShapeLib;

public class AlienShip extends Ship
{
    private static Logger logger = Logger.getLogger(AlienShip.class);

    private final static int ALIENBULLETLIFESPAN = (int) (2.5 * Utils.FRAMES_PER_SECOND);
    private final static int ALIENBULLETSPEED = (int) (240.0 / Utils.FRAMES_PER_SECOND);
    private final static int ALIEN_SPEED = (int) (90.0 / Utils.FRAMES_PER_SECOND);

    private double cruiseSpeed;

    private int weaponCooldownTime;
    private int weaponCooldownTimeLeft;

    private boolean outOfBounds = false;

    Utils.PolarCoordinate[] alienBling = { Utils.createPolarCoordinate(0, 10),
            Utils.createPolarCoordinate(180, 10),
            Utils.polarFromCartesian(Utils.createCartesianCoordinate(-4, -4)),
            Utils.polarFromCartesian(Utils.createCartesianCoordinate(4, -4)) };

    public AlienShip(double x, double y)
    {
        super("Alien", x, y, ShapeLib.ALIEN, GameObject.ALIENS);
        icing.add(new ShipIcing(this, alienBling));

        x_speed = (x_position < Utils.GAME_WIDTH / 2) ? ALIEN_SPEED : -ALIEN_SPEED;
        cruiseSpeed = x_speed;

        weaponCooldownTime = (int) (2.5 * Utils.FRAMES_PER_SECOND);
        weaponCooldownTimeLeft = 0;

        pilot = new StreakyPilot();

        value = 100;
    }

    public void update(GameState state)
    {
        x_speed = cruiseSpeed;
        logger.trace("updating alienShip");
        // uncomment this to make aliens expire after they leave the screen
        // instead of wrapping
        // if( x_speed > 0 && (x_position > Utils.GAME_WIDTH - x_speed) ||
        // x_speed < 0
        // && (x_position < Math.abs(x_speed)) )
        // {
        // outOfBounds = true;
        // }
        super.update(state);
        if( alive )
        {
            y_speed = 0;
            if( x_position > Utils.GAME_WIDTH || x_position < 0 )
            {
                // out of bounds
                outOfBounds = true;
            }
            int ord = pilot.getOrders(state);
            if( (ord & Pilot.LEFT) != 0 )
            {
                // angle down
                y_speed += ALIEN_SPEED;
            }
            if( (ord & Pilot.UP) != 0 )
            {
                // angle up
                y_speed += -ALIEN_SPEED;
            }
            if( (ord & Pilot.FIRE) != 0 )
            {
                if( weaponCooldownTimeLeft <= 0 )
                {
                    FIRE();
                }
            }
            if( (ord & Pilot.SPECIAL) != 0 )
            {
                if( special != null )
                {
                    special.engage();
                }
            }
        }
    }

    public void FIRE()
    {
        weaponCooldownTimeLeft = weaponCooldownTime;

        int dir = (int) (Math.random() * 4);
        double bdir;
        switch (dir)
        {
            case 0:
                bdir = 45;
                break;
            case 1:
                bdir = 135;
                break;
            case 2:
                bdir = 225;
                break;
            default:
                bdir = 315;
        }
        Bullet bill = new Bullet(x_position, y_position, bdir, ALIENBULLETSPEED, 1,
                ALIENBULLETLIFESPAN, this);
        add(bill);
    }

    public boolean isActive()
    {
        // if( !alive )
        // {
        // logger.info("isActive? " + (super.isActive() && !outOfBounds));
        // logger.info(" -icing.size(): " + icing.size());
        // for( Icing i : icing )
        // {
        // logger.info(i);
        // }
        // logger.info(" -bullets.size(): " + getObjects().size());
        // }
        return super.isActive() && !outOfBounds;
    }
}
